import axios from 'axios';

// 类型定义
interface AxiosConfig {
  baseURL: string;
  timeout: number;
  retry?: number;
  retryDelay?: number;
}

interface LoadingInstance {
  close: () => void;
}

// 默认配置
const DEFAULT_CONFIG: AxiosConfig = {
  baseURL: "/api",
  timeout: 3000,
  retry: 3, // 重试次数
  retryDelay: 1000 // 重试延迟
};

// 创建axios实例
const instance = axios.create(DEFAULT_CONFIG);

// 请求队列
const requestQueue = new Set<string>();

// Loading处理
let loadCount = 0;
let loadingInstance: LoadingInstance | null = null;

const showLoading = () => {
  loadCount++;
  if (loadCount === 1) {
    loadingInstance = ElLoading.service({
      fullscreen: false,
      text: "正在请求数据中....",
      background: "rgba(0, 0, 0, 0)",
    });
  }
};

const hideLoading = () => {
  loadCount--;
  if (loadCount === 0 && loadingInstance) {
    loadingInstance.close();
    loadingInstance = null;
  }
};

// 请求拦截
instance.interceptors.request.use(
  config => {
    // 添加请求标识
    const requestId = `${config.method}-${config.url}`;
    if (requestQueue.has(requestId)) {
      return Promise.reject(new Error('重复请求'));
    }
    requestQueue.add(requestId);

    // 添加token
    const token = sessionStorage.getItem('token');
    if (token) {
      config.headers['token'] = token;
    }

    // 显示loading
    showLoading();
    return config;
  },
  error => {
    return Promise.reject(error);
  }
);

// 响应拦截
instance.interceptors.response.use(
  response => {
    // 移除请求标识
    const requestId = `${response.config.method}-${response.config.url}`;
    requestQueue.delete(requestId);

    // 隐藏loading
    hideLoading();
    return response.data;
  },
  error => {
    // 移除请求标识
    if (error.config) {
      const requestId = `${error.config.method}-${error.config.url}`;
      requestQueue.delete(requestId);
    }

    // 隐藏loading
    hideLoading();

    // 错误处理
    const { response, config } = error;
    const status = response?.status;

    // 重试逻辑
    if (config && config.retry && status >= 500) {
      config.retry -= 1;
      if (config.retry > 0) {
        return new Promise(resolve => {
          setTimeout(() => {
            resolve(instance(config));
          }, config.retryDelay || 1000);
        });
      }
    }

    // 状态码处理
    const errorMap = new Map([
      [400, "请求错误"],
      [401, "未授权，请重新登录"],
      [403, "登录过期，请重新登录"],
      [404, "请求错误，未找到相应的资源"],
      [408, "请求超时"],
      [500, "服务器错误"],
      [502, "网关错误"],
      [503, "服务不可用"],
      [504, "网络超时"]
    ]);

    const message = errorMap.get(status) || "请求失败";
    ElMessage.error(message);

    return Promise.reject(error);
  }
);

export default instance;
